﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Engine.NetClasses
{
      public class PacketsBilder
    {
        HeaderPacket _headerPacket;
        byte[] _data;
        bool isCrypt;
        public bool NeedCrypt
        {
           
            get
            {
                return isCrypt;
            }
        }
        public HeaderPacket Header
        {
            get
            {
                return _headerPacket;
            }
        }
        public PacketsBilder(byte[] data, int offset)
        {
            byte[] tmpV=new byte[BitConverter.ToInt16(data, offset)+2];
            Array.Copy(data, offset, tmpV, 0, tmpV.Length);
            bool valid = checkHash(tmpV);
           if (valid)
           {
               
           
            _headerPacket = new HeaderPacket();            
            _headerPacket._ptype = data[offset+2];
            isCrypt = NetPacket.GetPacket(_headerPacket._ptype).NeedCrypt;
            _headerPacket._psize =(short)(BitConverter.ToInt16(data, offset)-(short)4);
            _data = new byte[_headerPacket._psize+2];
            if (isCrypt)
            {
               // Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
                byte[] tmp1 = new byte[_headerPacket._psize - 1];
                Array.Copy(data, offset + 3, tmp1, 0, tmp1.Length);
                byte[] tmp = Helpers.Crypter.crypt.Decrypt_ECB(tmp1);
                _headerPacket._psize = (short)(tmp.Length + 1);
                _data = new byte[_headerPacket._psize + 2];
                Array.Copy(BitConverter.GetBytes(_headerPacket._psize), 0, _data, 0, 2);
                _data[2] = _headerPacket._ptype;
                Array.Copy(tmp, 0, _data, 3, tmp.Length);
            }
            else
            {
                //Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
                //byte[] tmp = new byte[_headerPacket._psize - 1];
                //Array.Copy(data, offset + 3, tmp, 0, _headerPacket._psize + 2);
                //tmp = Helpers.Crypter.crypt.Decrypt_ECB(tmp);
                //Array.Copy(tmp, 0, _data, 3, tmp.Length);
                Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
            }
            }
           else
           {
               _headerPacket = new HeaderPacket();
               IPacket nullPac = NetPacket.GetPacket(0);
               _headerPacket._ptype = nullPac.PacketType;
               isCrypt = nullPac.NeedCrypt;
               _headerPacket._psize = nullPac.Size;
               _data = nullPac.GetByte();
           }
        }
        public PacketsBilder(byte[] data, int offset, Helpers.BlowFish cr)
        {
            byte[] tmpV = new byte[BitConverter.ToInt16(data, offset) + 2];
            Array.Copy(data, offset, tmpV, 0, tmpV.Length);
            bool valid = checkHash(tmpV);
            if (valid)
            {


                _headerPacket = new HeaderPacket();
                _headerPacket._ptype = data[offset + 2];
                isCrypt = NetPacket.GetPacket(_headerPacket._ptype).NeedCrypt;
                _headerPacket._psize = (short)(BitConverter.ToInt16(data, offset) - (short)4);
                _data = new byte[_headerPacket._psize + 2];
                if (isCrypt)
                {
                    // Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
                    byte[] tmp1 = new byte[_headerPacket._psize - 1];
                    Array.Copy(data, offset + 3, tmp1, 0, tmp1.Length);
                    byte[] tmp = cr.Decrypt_ECB(tmp1);
                    _headerPacket._psize = (short)(tmp.Length + 1);
                    _data = new byte[_headerPacket._psize + 2];
                    Array.Copy(BitConverter.GetBytes(_headerPacket._psize), 0, _data, 0, 2);
                    _data[2] = _headerPacket._ptype;
                    Array.Copy(tmp, 0, _data, 3, tmp.Length);
                }
                else
                {
                    //Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
                    //byte[] tmp = new byte[_headerPacket._psize - 1];
                    //Array.Copy(data, offset + 3, tmp, 0, _headerPacket._psize + 2);
                    //tmp = Helpers.Crypter.crypt.Decrypt_ECB(tmp);
                    //Array.Copy(tmp, 0, _data, 3, tmp.Length);
                    Array.Copy(data, offset, _data, 0, _headerPacket._psize + 2);
                }
            }
            else
            {
                _headerPacket = new HeaderPacket();
                IPacket nullPac = NetPacket.GetPacket(0);
                _headerPacket._ptype = nullPac.PacketType;
                isCrypt = nullPac.NeedCrypt;
                _headerPacket._psize = nullPac.Size;
                _data = nullPac.GetByte();
            }
        }

        public PacketsBilder(IPacket packet)
        {
            _headerPacket = new HeaderPacket();

            _headerPacket._ptype = packet.PacketType;
            isCrypt = packet.NeedCrypt;
            _headerPacket._psize = packet.Size;
            _data = packet.GetByte();
        }    
       
        public dynamic getStryct()
        {
            IPacket tmp;
            tmp=NetPacket.GetPacket(_headerPacket._ptype);            
            tmp.Convert(_data);
            
            if (tmp.isNull())
            {
                tmp = NetPacket.GetPacket(0);
            }
                  
            return tmp;
        }
        public byte[] getPacket()
        {
            if (isCrypt)
            {
                byte[] tmp = Crypt(_data);
                return tmp;
            }
            else
            {
                byte[] tmp = NoCrypt(_data);
                return tmp;
            }
        }
        public byte[] getPacket(Helpers.BlowFish cryptKey)
        {
            byte[] tmp = Crypt(_data, cryptKey);
            return tmp;
        }
        public byte[] Crypt(byte[] _data)
        {
            byte[] tmp=new byte[_data.Length-3];
            Array.Copy(_data,3,tmp,0,tmp.Length);
            tmp = Helpers.Crypter.crypt.Encrypt_ECB(tmp);
            byte[] data = new byte[3 + tmp.Length + 4];
            int Size = tmp.Length+1+ 4;
            byte[] sb = BitConverter.GetBytes(Size);
            data[0] = sb[0];
            data[1] = sb[1];
            data[2] = _data[2];
            sb = Helpers.Crypter.Calculate(tmp);
            Array.Copy(tmp, 0, data, 3, tmp.Length);
            Array.Copy(sb, 0, data, tmp.Length+3, sb.Length);
            return data;
        }
        public byte[] Crypt(byte[] _data,Helpers.BlowFish cr)
        {
            byte[] tmp = new byte[_data.Length - 3];
            Array.Copy(_data, 3, tmp, 0, tmp.Length);
           // tmp = Helpers.Crypter.crypt.Encrypt_ECB(tmp);
            tmp = cr.Encrypt_ECB(tmp);
            byte[] data = new byte[3 + tmp.Length + 4];
            int Size = tmp.Length + 1 + 4;
            byte[] sb = BitConverter.GetBytes(Size);
            data[0] = sb[0];
            data[1] = sb[1];
            data[2] = _data[2];
            sb = Helpers.Crypter.Calculate(tmp);
            Array.Copy(tmp, 0, data, 3, tmp.Length);
            Array.Copy(sb, 0, data, tmp.Length + 3, sb.Length);
            return data;
        }
        
        public byte[] NoCrypt(byte[] _data)
        {
            byte[] tmp = new byte[_data.Length - 3];
            Array.Copy(_data, 3, tmp, 0, tmp.Length);
           // tmp = Helpers.Crypter.crypt.Encrypt_ECB(tmp);
            byte[] data = new byte[3 + tmp.Length + 4];
            int Size = _headerPacket._psize + 4;
            byte[] sb = BitConverter.GetBytes(Size);
            data[0] = sb[0];
            data[1] = sb[1];
            data[2] = _data[2];
            sb = Helpers.Crypter.Calculate(tmp);
            Array.Copy(tmp, 0, data, 3, tmp.Length);
            Array.Copy(sb, 0, data, tmp.Length + 3, sb.Length);
            return data;
        }
        public bool checkHash(byte[] data)
        {
            byte[] tmp = new byte[BitConverter.ToInt16(data, 0) - 5];
            Array.Copy(data, 3, tmp, 0, tmp.Length);
            int sum = BitConverter.ToInt32(Helpers.Crypter.Calculate(tmp), 0);
            int sum2=BitConverter.ToInt32(data,2+ BitConverter.ToInt16(data, 0) - 4);
            if (sum == sum2 ) 
            {
                return true;
            }
            else
            {
            return false;
            }
        }

      
    }
}
